#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h> // 主机名解析

// 发送并接收ICMP回显请求
void ping(const std::string &target) {
    int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if(sockfd < 0) { std::cerr << "Socket error\n"; return; }
    
    struct sockaddr_in dest;
    memset(&dest, 0, sizeof(dest));
    dest.sin_family = AF_INET;
    inet_pton(AF_INET, target.c_str(), &dest.sin_addr);

    char buffer[8 + 20] = "";
    struct icmphdr *icmp = (struct icmphdr*)buffer;
    icmp->type = ICMP_ECHO;
    icmp->code = 0;
    icmp->checksum = 0;
    icmp->un.echo.id = getpid();
    icmp->un.echo.sequence = 1;
    icmp->checksum = htons(0xbeef); // 假设计算校验和

    sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&dest, sizeof(dest));

    // 接收响应
    char recvbuf[1024];
    socklen_t len = sizeof(dest);
    ssize_t n = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr*)&dest, &len);
    if(n > 0) std::cout << "Received response from " << target << "\n";
    else std::cerr << "No response\n";

    close(sockfd);
}

int main() {
    std::string target = "127.0.0.1"; // 目标地址
    ping(target); // 执行ping操作
    return 0;
}